// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: calendar.hpp 227 2008-09-15 13:33:40Z heavyzheng $
//

#ifndef ZZHENG_QUANT_DATES_CALENDAR_HPP_20080709__
#define ZZHENG_QUANT_DATES_CALENDAR_HPP_20080709__

#include <zzheng/quant/dates/config.hpp>
#include <zzheng/quant/dates/date.hpp>
#include <string>
#include <utility>
#include <vector>

namespace zzheng {
namespace quant {
namespace dates {

    //! This class represents a holiday calendar. When the holiday calendar is initialized (all
    //! weekends and holidays are registered), it should be used as an immutable const object.
    class calendar {

        typedef std::pair<date::month_type, date::day_type> month_day_pair;

    public:

        //! Constructs a holiday calendar of the specified business center. By default, Saturday
        //! and Sunday are registered as weekends, and no holidays are registered.
        //! \param center  the name of the business center.
        explicit calendar(const std::string& center);

        // Use auto-generated copy constructor.
        // Use auto-generated copy assignment.
        // Use auto-generated destructor.

        //! Returns the business center name of this holiday calendar.
        //! \return the business center name of this holiday calendar.
        const std::string& center() const;

        //! Checks if the specified date is a business day under this holiday calendar.
        //! \param d  the date to check for business day.
        //! \return true if this date is a business day, false otherwise.
        bool is_business_day(const date& d) const;

        //! Checks if the specified date is a weekend under this holiday calendar.
        //! \param d  the date to check for weekend.
        //! \return true if this date is a weekend, false otherwise.
        bool is_weekend(const date& d) const;

        //! Checks if the specified date is a holiday under this holiday calendar.
        //! \param d  the date to check for holiday.
        //! \return true if this date is a holiday, false otherwise.
        bool is_holiday(const date& d) const;

        //! Registers a weekend to this holiday calendar.
        //! \param weekend  the weekend to register, typically Saturday and Sunday.
        void add_weekend(date::weekday_type weekend);

        //! Clears all the registered weekends from this holiday calendar.
        void clear_weekends();

        //! Registers an annual holiday to this holiday calendar.
        //! \param month  the month of the holiday to register.
        //! \param day    the day of month of the holiday to register.
        void add_holiday(date::month_type month, date::day_type day);

        //! Clears all the registered holidays from this holiday calendar.
        void clear_holidays();

    private:

        std::string                     center_;   //!< Business center name.
        std::vector<date::weekday_type> weekends_; //!< Registered weekends.
        std::vector<month_day_pair>     holidays_; //!< Registered annual holidays.

    }; // class calendar

} // namespace zzheng::quant::dates
} // namespace zzheng::quant
} // namespace zzheng

#endif // ZZHENG_QUANT_DATES_CALENDAR_HPP_20080709__



